﻿using System;
using System.Web.Security;
using Jayden.Dll.Core.Enums;
using Jayden.Dll.Core.Membership;
using Jayden.Dll.Web.Events;
using Jayden.Dll.Web.Helper;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.Json;

namespace Jayden.Dll.Web.Controls
{
	public class RegisterForm : Form
	{

		public delegate void OnRegisterSuccess(HttpHandlerContext context, User user);
		public delegate void OnRegisterFailed(HttpHandlerContext context, MembershipCreateStatus status);

		public class RegisterCommandHandler : HttpCommandHandler
		{
			public RegisterCommandHandler() : this("Register") { }
			public RegisterCommandHandler(string command)
				: base(command)
			{
				RegisterEvent("RegisterFailed");
				RegisterEvent("RegisterSuccess");
			}
			public event OnRegisterFailed RegisterFailed { add { AddEvent<OnRegisterFailed>("RegisterFailed", value); } remove { RemoveEvent<OnRegisterFailed>("RegisterFailed", value); } }
			public event OnRegisterSuccess RegisterSuccess { add { AddEvent<OnRegisterSuccess>("RegisterSuccess", value); } remove { RemoveEvent<OnRegisterSuccess>("RegisterSuccess", value); } }

			public static void SendEmailValidation(Uri uri, Mailer mailer, User user)
			{
				uri["userEmail"] = user.Email;
				uri["guid"] = user.Guid;
				mailer.Send(new string[] { user.Email }, null, null,
					"Validate your email for your newly registred account.",
					"You just subscribed for a new account. Validate your email now : <a href=\"" + uri.ToString(false) + "\">Click here to validate your email</a>."
				);

			}

			protected override void ProcessCommand(HttpHandlerContext context, string command)
			{

				string username = context.Context.Request["username"];
				string password = context.Context.Request["password"];
				string email = context.Context.Request["email"];
				string lastName = context.Context.Request["lastName"];
				string firstName = context.Context.Request["firstName"];
				string passwordQuestion = context.Context.Request["passwordQuestion"];
				string passwordAnswer = context.Context.Request["passwordAnswer"];
				string gender = context.Context.Request["gender"];
				string birthDate = context.Context.Request["birthDate"];

				MembershipCreateStatus status;
				User user = Membership.CreateUser(username, password, email, passwordQuestion, passwordAnswer, true, out status) as User;

				if (user != null)
				{
					user.FirstName = firstName;
					user.LastName = lastName;
					user.Gender = (Gender)Enum.Parse(typeof(Gender), gender, true);
					user.BirthDate = HtmlHelper.FromHtmlDate(birthDate, DateTime.MinValue);
					Membership.UpdateUser(user);
					Mailer mailer = context.GetMailer(null);
					if (mailer != null)
					{
						Uri uri = new Uri(context.Request.Url);
						SendEmailValidation(uri, mailer, user);
					}
					Invoke("RegisterSuccess", context, user);
				}
				else
					Invoke("RegisterFailed", context, status);

			}
		}

		private Input m_Username;
		private Input m_Password;
		private Input m_ConfirmPassword;
		private Img m_PasswordMatch;
		private Input m_Email;
		private Input m_LastName;
		private Input m_FirstName;
		private Input m_PasswordQuestion;
		private Input m_PasswordAnswer;
		private Select m_Gender;
		private Input m_BirthDate;

		private Button m_Register;

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			base.Load(node, loader);

			if (Id == null)
				Id = "registerForm";
			m_Username = GetFormElement<Input>("username");
			m_Password = GetFormElement<Input>("password");
			m_ConfirmPassword = GetElementByServerId<Input>("confirmPassword", true);
			m_PasswordMatch = GetElementByServerId<Img>("passwordMatch", true);
			m_Email = GetFormElement<Input>("email");
			m_LastName = GetFormElement<Input>("lastName");
			m_FirstName = GetFormElement<Input>("firstName");
			m_PasswordQuestion = GetFormElement<Input>("passwordQuestion");
			m_PasswordAnswer = GetFormElement<Input>("passwordAnswer");
			m_Gender = GetFormElement<Select>("gender");
			m_BirthDate = GetFormElement<Input>("birthDate");
			m_Register = GetFormElement<Button>("register", "command");
		}

		public void LinkLabels()
		{
			FindLabel(m_Username);
			FindLabel(m_Password);
			FindLabel(m_Email);
			FindLabel(m_LastName);
			FindLabel(m_FirstName);
			FindLabel(m_PasswordQuestion);
			FindLabel(m_PasswordAnswer);
			FindLabel(m_Gender);
			FindLabel(m_BirthDate);
			FindLabel(m_Register);
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{
			string guid = context.Request["guid"];
			string userEmail = context.Request["userEmail"];
			if (!string.IsNullOrWhiteSpace(guid) && !string.IsNullOrWhiteSpace(userEmail))
			{
				string username = Membership.GetUserNameByEmail(userEmail);
				if (!string.IsNullOrWhiteSpace(username))
				{
					User user = Membership.GetUser(username) as User;
					if (user != null && user.Guid == guid && !user.IsEmailValidated)
					{
						user.IsEmailValidated = true;
						Membership.UpdateUser(user);

						Clear();
						AddText<P>(context.Translator.Translate("Your email, '{0}', for the account '{1}', has been validated successfully.", userEmail, username));
					}
				}
			}

			base.ProcessHtmlRequest(context);
			LinkLabels();
			RegisterCommandHandler handler = context.HandlerManager.GetHandler<RegisterCommandHandler>();
			handler.RegisterSuccess += new OnRegisterSuccess(RegisterSuccess);
			handler.RegisterFailed += new OnRegisterFailed(RegisterFailed);
		}

		void RegisterFailed(HttpHandlerContext context, MembershipCreateStatus status)
		{
			P p = AddText<P>("The registration process failed. (status is '" + status + "')");
			if (context.Json != null)
			{
				JsonObject form = new JsonObject();
				form.Add("html", ToInnerHtml(context.Translator));
				context.Json.Add(Id, form);
			}
		}

		void RegisterSuccess(HttpHandlerContext context, User user)
		{
			Clear();
			P p = AddText<P>("You are now registred, please check your email for validation and login.");
			if (context.Json != null)
			{
				JsonObject form = new JsonObject();
				form.Add("html", ToInnerHtml(context.Translator));
				context.Json.Add(Id, form);
			}
		}


		public override void ProcessJsRequest(HttpHandlerContext context)
		{
			base.ProcessJsRequest(context);

			string id = Id;

			context.Js[id].AppendAjaxHtmlHandler(this, false, false);
			context.Js[id].AppendOnInit(@"
	var $password = $('#" + m_Password.Id + @"');
	var $confirmPassword = $('#" + m_ConfirmPassword.Id + @"');
	var $register = $('#" + m_Register.Id + @"');
	var $passwordMatch = $('#" + m_PasswordMatch.Id + @"');
	
	var checkPasswords = function() {
		if($password.val() !== '' && $password.val() === $confirmPassword.val()) {
			$register.removeAttr('disabled');
			$passwordMatch.attr('src', '/Images/Icons/checkmark.png').attr('alt', 'Valid').attr('title', 'The passwords match.');
		} else {
			$register.attr('disabled', 'disabled');
			$passwordMatch.attr('src', '/Images/Icons/delete.png').attr('alt', 'Invalid').attr('title', 'The passwords don\'t match.');
		}
	};

	$password.keyup(checkPasswords);
	$confirmPassword.keyup(checkPasswords);

	checkPasswords();
");

		}
	}
}